package com.wl.springsecuritystudy.thread.support;

import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
import org.springframework.transaction.support.TransactionSynchronizationAdapter;
import org.springframework.transaction.support.TransactionSynchronizationManager;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.Future;

@Slf4j
@Component
public class AfterCommitExecutorImpl extends TransactionSynchronizationAdapter implements AfterCommitExecutor {

    private ThreadLocal<List<Runnable>> threadLocal_runnable = new ThreadLocal<>();

    @Resource
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;



    @Override
    public void execute(Runnable command) {

        if(!TransactionSynchronizationManager.isSynchronizationActive()){
            command.run();
            return;
        }

        List<Runnable> runnables = threadLocal_runnable.get();
        if(CollectionUtils.isEmpty(runnables)){
            runnables = Lists.newArrayList();
            threadLocal_runnable.set(runnables);
            TransactionSynchronizationManager.registerSynchronization(this);
        }
        runnables.add(command);
    }



    @Override
    public void afterCommit() {
        List<Runnable> runnables = threadLocal_runnable.get();
        log.info("事物提交后执行:{} 个线程",runnables.size());
        if(CollectionUtils.isNotEmpty(runnables)){
            try {
                for (Runnable runnable : runnables) {

                    Future<?> submit = threadPoolTaskExecutor.submit(runnable);

                    try {
                        submit.get();
                    }catch (Exception e){
                        log.info("线程执行异常");
                        e.printStackTrace();
                    }

                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    @Override
    public void afterCompletion(int status) {
        log.info("事务执行完成 状态={}", status == STATUS_COMMITTED ? "COMMITTED" : "ROLLED_BACK");
        threadLocal_runnable.remove();
    }
}
